package com.bfxy.test1;

import java.nio.ByteBuffer;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.bfxy.disruptor.common.Disruptor;
import com.bfxy.disruptor.common.ProducerType;
import com.bfxy.disruptor.common.RingBuffer;
import com.bfxy.disruptor.common.waitStraty.BlockingWaitStrategy;

public class Main {
	
	public static void main(String[] args) {
		OrderEventFactory orderEventFactory = new OrderEventFactory();
		int ringBufferSize = 4;
		ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
		
		//eventFactory: 消息(event)工厂对象 。 ringBufferSize: 容器的长度。数组长度的参数之一，也是预加载的长度。
		//ProducerType: 单生产者 还是 多生产者。 waitStrategy: 等待策略
		//ringBuffer是Disruptor的属性。
		// bufferSize、waitStrategy、cursor、gatingSequences是SingleProducer单生产者的属性。
		// SingleProducer单生产者、生产者的bufferSize、entries数组、是ringBuffer的属性。
		//创建ringbuffer，单或多生产者。
		Disruptor<Order> disruptor = new Disruptor<Order>(orderEventFactory,/*消息工厂*/
				ringBufferSize,/*容器的长度*/ executor,/*线程池*/ ProducerType.MULTI,/* duo生产者模式*/
				new BlockingWaitStrategy()); /*生产者会和消费者的等待策略，阻塞策略*/
		
		//创建消费者，并放到consumerRepository。多个消费者多个线程，封装成多个SingleConsumer，然后SingleConsumer直接操作ringbuffer。
		disruptor.handleEventsWith(new Consumer1(),new Consumer1()); 
		
		//3. 启动disruptor。消费者线程跑起来，一个消费者一个线程。
		disruptor.start();
		
		//4. 获取实际存储数据的容器: 容器的名字叫做RingBuffer，环形的buffer，把消息扔到Disruptor这个容器中，
		RingBuffer<Order> ringBuffer = disruptor.getRingBuffer();
		
		for (int i = 0; i < 10; i++) {//多个生产者，每个生产者1个线程。
			//多个生产者多个线程不会直接操作Ringbuffer，而是通过ringbuffer里面的单或者多生产者sequencer来操作ringbuffer。多个生产者多个线程但是只有一个单或者多生产者的sequencer。
			//生产者没有栅栏，只有消费者才有栅栏，并且栅栏里面也有单或者多生产者sequencer。
			new Thread(new Runnable() {
				public void run() {
					//生产者，投递一个个的消息
					OrderEventProducer producer = new OrderEventProducer(ringBuffer);
					ByteBuffer bb = ByteBuffer.allocate(8);//初始化8个字节长度，因为OrderEvent里面的value是long
					for(long i = 0 ; i < 5; i ++){
						bb.putLong(0, i);//把i放在第0个位置开始
						producer.sendData(bb);//往ringBuffer投递消息，生产者生产消息
					}
				}
			}).start();
		}
		
		//用完关闭
		disruptor.shutdown();
		executor.shutdown();
		
		
		/*
		 不管是单生产还是多生产模式，有多个生产线程，只有一个单或多生产者sequencer（由Disruptor创建）。里面有cursor,就是多个生产者的位置。
		 多个消费者多个线程，有多个SingleConsumer，每个SingleConsumer有这个消费者的位置sequence。
		 同时多个消费者公用一个栅栏，这个栅栏里面也有这个唯一的单或多生产者sequencer。生产者没有栅栏，只有消费者有栅栏。
		*/
	}
}
